﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Unijovem.Domain;
using Unijovem.UI.Models;

namespace Unijovem.UI.Controllers
{
    public class ArquivoController : ControllerBase<ArquivoModel, Arquivo>
    {
        #region Upload

        public ActionResult Upload(int id, ArquivoModel.TipoArquivo tipo, string redirectAction = null, string redirectController = null, bool multiplosArquivos = true)
        {
            string caminho = ArquivoModel.SelecionarCaminhoImagem(tipo);

            var models = new List<ArquivoModel> { new ArquivoModel { IdExterno = id, Caminho = caminho, Tipo = tipo } };

            ViewBag.RedirectAction = redirectAction;
            ViewBag.RedirectController = redirectController;
            ViewBag.MultiplosArquivos = multiplosArquivos;

            return View(models);
        }

        [HttpPost]
        public ActionResult Upload(IEnumerable<HttpPostedFileBase> fileUpload, FormCollection collection)
        {
            var caminho = collection.GetValue("Caminho").AttemptedValue;
            var idExterno = int.Parse(collection.GetValue("IdExterno").AttemptedValue);
            ArquivoModel.TipoArquivo tipo;
            Enum.TryParse(collection.GetValue("Tipo").AttemptedValue, out tipo);

            var models = (from file in fileUpload
                          where file != null && file.ContentLength > 0
                          select SalvarArquivo(file, caminho, tipo, idExterno)).ToList();

            Session[string.Concat("ArquivoExterno", idExterno)] = models;

            var redirectAction = collection.GetValue("RedirectAction").AttemptedValue;
            var redirectController = collection.GetValue("RedirectController").AttemptedValue;

            return string.IsNullOrEmpty(redirectAction)
                       ? RedirectToAction("ListarEdicao", new {idExterno})
                       : (string.IsNullOrEmpty(redirectController)
                              ? RedirectToAction(redirectAction)
                              : RedirectToAction(redirectAction, redirectController));
        }

        public ArquivoModel SalvarArquivo(HttpPostedFileBase file, string caminho, ArquivoModel.TipoArquivo tipo, int idExterno)
        {
            var nomeArquivo = ResolverCaminhoArquivo(file, caminho);

            var model = SalvarDominio(nomeArquivo, tipo, idExterno);

            if (model != null)
            {
                //model.Nome = Url.Content(Path.Combine(caminho, nomeArquivo));
                model.Nome = nomeArquivo;
                model.Caminho = caminho;
                return model;
            }

            return null;
        }

        private ArquivoModel SalvarDominio(string nomeArquivo, ArquivoModel.TipoArquivo tipo, int idExterno)
        {
            switch (tipo)
            {
                case ArquivoModel.TipoArquivo.Evento:
                    return SalvarImagemDominio(nomeArquivo, idExterno);
                case ArquivoModel.TipoArquivo.MaterialApoio:
                    return SalvarMaterialApoio(nomeArquivo, idExterno);
                case ArquivoModel.TipoArquivo.Aviso:
                    return SalvarAviso(nomeArquivo);
                case ArquivoModel.TipoArquivo.FotoPessoa:
                case ArquivoModel.TipoArquivo.Autor:
                    return SalvarArquivoGenerico(nomeArquivo);
            }

            return null;
        }

        private ArquivoModel SalvarArquivoGenerico(string nomeArquivo)
        {
            var dominio = new Arquivo { Ativo = true, Nome = nomeArquivo };
            dominio.Save(dominio);

            return new ArquivoModel().CriarViewModel(dominio);
        }

        private ArquivoModel SalvarAviso(string nomeArquivo)
        {
            var dominio = new Aviso { Arquivo = new Arquivo { Ativo = true, Nome = nomeArquivo }, DataInclusao = DateTime.Now, Ativo = true };
            dominio.Save();

            Session[string.Concat("Arquivo", dominio.Arquivo.Id)] = dominio.Arquivo;

            return new ArquivoModel().CriarViewModel(dominio.Arquivo);
        }

        private ArquivoModel SalvarMaterialApoio(string nomeArquivo, int idExterno)
        {
            var dominio = new MaterialApoio { Arquivo = new Arquivo { Ativo = true, Nome = nomeArquivo }, IdEvento = idExterno };
            dominio.Save();

            Session[string.Concat("Arquivo", dominio.Arquivo.Id)] = dominio.Arquivo;

            return new ArquivoModel().CriarViewModel(dominio.Arquivo);
        }

        private ArquivoModel SalvarImagemDominio(string nomeArquivo, int idEvento)
        {
            var dominio = new EventoImagem { Arquivo = new Arquivo { Ativo = true, Nome = nomeArquivo }, IdEvento = idEvento };
            dominio.Save();

            Session[string.Concat("Arquivo", dominio.Arquivo.Id)] = dominio.Arquivo;

            return new ArquivoModel().CriarViewModel(dominio.Arquivo);
        }

        private string ResolverCaminhoArquivo(HttpPostedFileBase file, string caminho)
        {
            string nomeArquivo = string.Concat(Guid.NewGuid(), ObterFormatoArquivo(file.FileName));
            if (caminho.StartsWith("~/")) caminho = Server.MapPath(caminho);

            var path = Path.Combine(caminho, nomeArquivo);

            while (System.IO.File.Exists(path))
            {
                nomeArquivo = Guid.NewGuid().ToString();
                path = Path.Combine(caminho, nomeArquivo);
            }

            file.SaveAs(path);
            return nomeArquivo;
        }

        private string ObterFormatoArquivo(string nomeArquivo)
        {
            return string.Concat(".", nomeArquivo.Split('.').Last());
        }

        #endregion

        #region Editar

        [HttpPost]
        public ActionResult Editar(FormCollection collection)
        {
            var model = ArquivoModel.Converter(collection);
            var models = (List<ArquivoModel>)Session[string.Concat("ArquivoExterno", model.IdExterno)];
            var index = models.FindIndex(m => m.Id == model.Id);

            model = SalvarEdicao(model, true);
            models[index] = model;
            Session[string.Concat("ArquivoExterno", model.IdExterno)] = models;

            return RedirectToAction("ListarEdicao", new { idExterno = model.IdExterno });
        }

        public ActionResult ListarEdicao(int idExterno)
        {
            var models = Session[string.Concat("ArquivoExterno", idExterno)];

            return View(models);
        }

        public ActionResult ListarEdicaoPartial(int idExterno)
        {
            var models = Session[string.Concat("ArquivoExterno", idExterno)];

            return PartialView("ListarEdicao", models);
        }

        #endregion

        public ActionResult SalvarTitulo(string titulo, string id, string idExterno)
        {
            SalvarEdicao(idExterno, id, titulo, null);
            return Json(new { success = true });
        }

        public ActionResult SalvarDescricao(string descricao, string id, string idExterno)
        {
            SalvarEdicao(idExterno, id, null, descricao);
            return Json(new { success = true });
        }

        private void SalvarEdicao(string idExterno, string id, string titulo, string descricao)
        {
            var models = (List<ArquivoModel>)Session[string.Concat("ArquivoExterno", idExterno)];
            var model = models.First(m => m.Id == int.Parse(id));
            var index = models.IndexOf(model);

            if (titulo != null)
                model.Titulo = titulo;
            else
                model.Descricao = descricao;

            model = SalvarEdicao(model, true);
            models[index] = model;
            Session[string.Concat("ArquivoExterno", idExterno)] = models;
        }
    }
}
